/**
 * @fileoverview Tests for no-lonely-if rule.
 * @author Brandon Mills
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const rule = require("../../../lib/rules/no-lonely-if"),
	RuleTester = require("../../../lib/rule-tester/rule-tester");

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const ruleTester = new RuleTester();
const errors = [{ messageId: "unexpectedLonelyIf", type: "IfStatement" }];

ruleTester.run("no-lonely-if", rule, {
	// Examples of code that should not trigger the rule
	valid: [
		"if (a) {;} else if (b) {;}",
		"if (a) {;} else { if (b) {;} ; }",
		"if (a) if (a) {} else { if (b) {} } else {}",
	],

	// Examples of code that should trigger the rule
	invalid: [
		{
			code: "if (a) {;} else { if (b) {;} }",
			output: "if (a) {;} else if (b) {;}",
			errors,
		},
		{
			code:
				"if (a) {\n" +
				"  foo();\n" +
				"} else {\n" +
				"  if (b) {\n" +
				"    bar();\n" +
				"  }\n" +
				"}",
			output:
				"if (a) {\n" +
				"  foo();\n" +
				"} else if (b) {\n" +
				"    bar();\n" +
				"  }",
			errors,
		},
		{
			code:
				"if (a) {\n" +
				"  foo();\n" +
				"} else /* comment */ {\n" +
				"  if (b) {\n" +
				"    bar();\n" +
				"  }\n" +
				"}",
			output:
				"if (a) {\n" +
				"  foo();\n" +
				"} else /* comment */ if (b) {\n" +
				"    bar();\n" +
				"  }",
			errors,
		},
		{
			code:
				"if (a) {\n" +
				"  foo();\n" +
				"} else {\n" +
				"  /* otherwise, do the other thing */ if (b) {\n" +
				"    bar();\n" +
				"  }\n" +
				"}",
			output: null,
			errors,
		},
		{
			code:
				"if (a) {\n" +
				"  foo();\n" +
				"} else {\n" +
				"  if /* this comment is ok */ (b) {\n" +
				"    bar();\n" +
				"  }\n" +
				"}",
			output:
				"if (a) {\n" +
				"  foo();\n" +
				"} else if /* this comment is ok */ (b) {\n" +
				"    bar();\n" +
				"  }",
			errors,
		},
		{
			code:
				"if (a) {\n" +
				"  foo();\n" +
				"} else {\n" +
				"  if (b) {\n" +
				"    bar();\n" +
				"  } /* this comment will prevent this test case from being autofixed. */\n" +
				"}",
			output: null,
			errors,
		},
		{
			code: "if (foo) {} else { if (bar) baz(); }",
			output: "if (foo) {} else if (bar) baz();",
			errors,
		},
		{
			// Not fixed; removing the braces would cause a SyntaxError.
			code: "if (foo) {} else { if (bar) baz() } qux();",
			output: null,
			errors,
		},
		{
			// This is fixed because there is a semicolon after baz().
			code: "if (foo) {} else { if (bar) baz(); } qux();",
			output: "if (foo) {} else if (bar) baz(); qux();",
			errors,
		},
		{
			// Not fixed; removing the braces would change the semantics due to ASI.
			code:
				"if (foo) {\n" +
				"} else {\n" +
				"  if (bar) baz()\n" +
				"}\n" +
				"[1, 2, 3].forEach(foo);",
			output: null,
			errors,
		},
		{
			// Not fixed; removing the braces would change the semantics due to ASI.
			code:
				"if (foo) {\n" +
				"} else {\n" +
				"  if (bar) baz++\n" +
				"}\n" +
				"foo;",
			output: null,
			errors,
		},
		{
			// This is fixed because there is a semicolon after baz++
			code:
				"if (foo) {\n" +
				"} else {\n" +
				"  if (bar) baz++;\n" +
				"}\n" +
				"foo;",
			output: "if (foo) {\n" + "} else if (bar) baz++;\n" + "foo;",
			errors,
		},
		{
			// Not fixed; bar() would be interpreted as a template literal tag
			code:
				"if (a) {\n" +
				"  foo();\n" +
				"} else {\n" +
				"  if (b) bar()\n" +
				"}\n" +
				"`template literal`;",
			output: null,
			languageOptions: { ecmaVersion: 6 },
			errors,
		},
		{
			code:
				"if (a) {\n" +
				"  foo();\n" +
				"} else {\n" +
				"  if (b) {\n" +
				"    bar();\n" +
				"  } else if (c) {\n" +
				"    baz();\n" +
				"  } else {\n" +
				"    qux();\n" +
				"  }\n" +
				"}",
			output:
				"if (a) {\n" +
				"  foo();\n" +
				"} else if (b) {\n" +
				"    bar();\n" +
				"  } else if (c) {\n" +
				"    baz();\n" +
				"  } else {\n" +
				"    qux();\n" +
				"  }",
			errors,
		},
	],
});
